﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using AutoMapper;
using MediatR;
using MS.BasicData.Domain;
using MS.BasicData.Infrastructure;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

using static MS.BasicData.Read.API.Applications.UserInfos.LoginRequestHandler;
using MS.BasicData.Infrastructure.IBaseRepository;

namespace MS.BasicData.Read.API.Applications.UserInfos
{
    public class LoginRequestHandler : IRequestHandler<LoginRequestModel, ApiRestult>
    {

        /// <summary>
        /// 用户信息仓储
        /// </summary>
        private readonly IUserBaseRepository _userbaserepository;

        private readonly IConfiguration _configuration;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userbaserepository"></param>
        /// <param name="configuration"></param>
        public LoginRequestHandler(IUserBaseRepository userbaserepository, IConfiguration configuration)
        {
            _userbaserepository = userbaserepository;
            _configuration = configuration;
        }

        public async Task<ApiRestult> Handle(LoginRequestModel request, CancellationToken cancellationToken)
        {
            ApiRestult result = new ApiRestult()
            {
                isSuc = true,
                Code = Restult.Success,
                Message = "登录成功"
            };
            var list = await _userbaserepository.GetAll(a => a.UserNick == request.UserNick);
            if(list == null)
            {
                result.Code = Restult.Fail;
                result.Message = "用户不存在";
                result.isSuc = false;
                return result;
            }
            //验证密码
            if (list.Password != request.Password)
            {
                result.Code = Restult.Fail;
                result.Message = "密码错误";
                result.isSuc = false;
                return result;
            }
            //生产jwt令牌
            var Token = GenerateToken(list.UserName);
            result.Data = new { list, Token };
            return result;
        }

        public string GenerateToken(string username)
        {
            var claims = new[]
            {
            new Claim(JwtRegisteredClaimNames.Sub, username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(30),
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);

        }

    }

    public class LoginRequestModel : IRequest<ApiRestult>
    {
        /// <summary>
        /// 用户昵称
        /// </summary>
        public string? UserNick { get; set; }
        /// <summary>
        /// 密码
        /// </summary>
        public string? Password { get; set; }
    }

    public class LoginResponseModel
    {
        /// <summary>
        /// 用户主键
        /// </summary>
        public int UserInfoId { get; set; }
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; } = string.Empty;
        /// <summary>
        /// 角色ID
        /// </summary>
        public int RoleId { get; set; }
        /// <summary>
        /// 用户昵称
        /// </summary>
        public string UserNick { get; set; } = string.Empty;
        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; } = string.Empty;
        /// <summary>
        /// 错误次数
        /// </summary>
        public int ErrNum { get; set; }
        /// <summary>
        /// 用户状态
        /// </summary>
        public bool IsSuc { get; set; }

        public string Token { get; set; }
    }
}



